package game.entity;



import game.ability.AbilityManager;
import game.ability.AbsAbility;
import game.ability.IMoving;
import game.helper.Input;
import game.logic.GameControl;
import game.shared.Constants;

import java.util.ArrayList;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;

public class AbsSprite extends Sprite{

	int id;
	SpriteManager spriteMamanger;
	ArrayList<AbsAnimation> animations;
	protected int curAnimationIndex;
	AbilityManager abilities;
	IMoving mover;
	Input input;
	protected float hp;
	protected float mana;
	Vector2 hpPosition;
	BitmapFont font;
	protected boolean bPause;
	
	public void setbPause(boolean bPause) {
		this.bPause = bPause;
		for (AbsAnimation animation : animations) {
			animation.setbPause(bPause);
		}
	}
	
	public AbsSprite(AbsSprite absSprite){
		id = ++Constants.ID_SPRITE;
		spriteMamanger = absSprite.spriteMamanger;
		animations = new ArrayList<AbsAnimation>();
		curAnimationIndex = absSprite.curAnimationIndex;
		abilities = new AbilityManager();
		mover = absSprite.mover;
		input = absSprite.input;
		for(int i=0; i< absSprite.animations.size(); i++)
			animations.add(new AbsAnimation(absSprite.animations.get(i)));
		font = new BitmapFont();
		hp = absSprite.hp;
		mana = 100;
		hpPosition = new Vector2(getX(), getY());
	}
	
	public AbsSprite(SpriteManager _SpriteManager, String animationImgPath, int idAnimation, float frameDuration, int frame_rows, int frame_cols) {
		id = ++Constants.ID_SPRITE;
		abilities = new AbilityManager();
		spriteMamanger = _SpriteManager;
		animations = new ArrayList<AbsAnimation>();
		animations.add(new AbsAnimation(idAnimation,animationImgPath,frameDuration, frame_rows, frame_cols));
		font = new BitmapFont();
		hp = 100;
		mana = 100;
		hpPosition = new Vector2(getX(), getY());
	}
	
	public AbsSprite(SpriteManager _SpriteManager, String animationImgPath, int idAnimation, float frameDuration, int scrX, int scrY, int frameWidth, int frameHeight, int frame_rows, int frame_cols)
	{
		id = ++Constants.ID_SPRITE;
		abilities = new AbilityManager();
		spriteMamanger = _SpriteManager;
		animations = new ArrayList<AbsAnimation>();
		animations.add(new AbsAnimation(idAnimation, animationImgPath, frameDuration, scrX, scrY, frameWidth, frameHeight, frame_rows, frame_cols));
		font = new BitmapFont();
		hp = 100;
		mana = 100;
		hpPosition = new Vector2(getX(), getY());
	}
	
	public AbsSprite(SpriteManager _SpriteManager, String configFilePath)
	{
		id = ++Constants.ID_SPRITE;
		spriteMamanger = _SpriteManager;
		abilities = new AbilityManager();
		animations = new ArrayList<AbsAnimation>();
		LoadFileConfig(configFilePath);
		font = new BitmapFont();
		hp = 100;
		mana = 100;
		hpPosition = new Vector2(getX(), getY());
		this.setSlower(1);
	}
	
	private void LoadFileConfig(String configFilePath)
	{
		FileHandle file = Gdx.files.internal(configFilePath);
		String strCfg = file.readString();
		String[] lines = strCfg.split("\r\n");
		for(int i=0; i<lines.length; i++)
		{
			String[] values = lines[i].split(";");

			int aid = Integer.parseInt(values[0]);
			String path = values[1];
			float duration = Float.parseFloat(values[2]);
			int x = Integer.parseInt(values[3]);
			int y = Integer.parseInt(values[4]);
			int w = Integer.parseInt(values[5]);
			int h = Integer.parseInt(values[6]);
			int r = Integer.parseInt(values[7]);
			int c = Integer.parseInt(values[8]);
			Texture texture = new Texture(Gdx.files.internal(path));
			animations.add(new AbsAnimation(aid, texture, duration, x, y, w, h, r, c));
		}
	}

	public void render(SpriteBatch spriteBatch){
		abilities.render(spriteBatch);
		animations.get(curAnimationIndex).draw(spriteBatch, this.getX(), this.getY());
		//showHp(spriteBatch);
	}
	private void showHp(SpriteBatch sb){
		font.draw(sb, String.valueOf(hp), getX(), getY());
	}
	public void setHpPosition(int x, int y){
		hpPosition.set(x, y);
	}
	
	public void renderShape(){
		abilities.renderShape();
	}
	
	public void update()
	{
		abilities.update();
		if(mover != null)
			mover.run(this);
	}
	

	@Override
	public float getWidth() {
		return animations.get(curAnimationIndex).getDimension().x;
	}
	
	@Override
	public float getHeight() {
		return animations.get(curAnimationIndex).getDimension().y;
	}
	
	public int getID() 
	{
		return id;
	}
	
	public boolean setState(int stateID)
	{
		for(int i=0; i<animations.size(); i++)
		{
			int id = animations.get(i).getID();
			if(id == stateID)
			{
				this.curAnimationIndex = i;
				return true;
			}
		}
		return false;
	}
	
	public boolean haveState(int stateID)
	{
		for(int i=0; i<animations.size(); i++)
		{
			if(animations.get(i).getID() == stateID)
				return true;
		}
		return false;
	}
	public int getCurrentState()
	{
		return animations.get(curAnimationIndex).getID();
	}
	
	
	public void setMoving(IMoving mover)
	{
		this.mover = mover;
	}
	
	@Override
	public Rectangle getBoundingRectangle() {
		Vector2 wh = animations.get(curAnimationIndex).getDimension();
		return new Rectangle(this.getX(),this.getY(),wh.x,wh.y);
	}

	public float getSpeed() {
		if(mover != null)
			return mover.getSpeed();
		return 0;
	}

	public void setSpeed(float speed) {
		if(mover != null)
			mover.setSpeed(speed);
	}
	
	public void setSlower(float slower) {
		if(mover != null)
			mover.setSlower(slower);
		for (AbsAnimation animation : animations) {
			animation.setSlower(slower);
		}
	}
	
	public void setInput(Input _input){
		this.input = _input;
	}
	public Input getInput(){
		return this.input;
	}
	
	public void addAbility(AbsAbility ability)
	{
		this.abilities.add(ability); 
	}	
	
	public void action(int abilityID)
	{
		abilities.action(abilityID);
	}

	public float getHp() {
		return hp;
	}

	public void setHp(float hp) {
		this.hp = hp;
	}
	
	public float getMana() {
		return mana;
	}
	
	public void setMana(float mana) {
		this.mana = mana;
	}



	public float getSlower() {
		return mover == null ? 0 : mover.getSlower();
	}
}
